package algorithms.SyntacticMatchers;



import java.util.ArrayList;
import java.util.Iterator;
import java.util.StringTokenizer;
import java.util.Vector;

import com.nexagis.jawbone.Dictionary;
import com.nexagis.jawbone.IndexTerm;
import com.nexagis.jawbone.PartOfSpeech;
import com.nexagis.jawbone.Synset;
import com.nexagis.jawbone.WordData;
import com.nexagis.jawbone.filter.StartsWithFilter;
import com.nexagis.jawbone.filter.TermFilter;


public class WordNet  {

	
	public Iterator<IndexTerm> relatedWordsIterator;
		/**
		 * 
		 * @param a 
		 * @param b 
		 * @return the number of matching related words the two words have. each word is looked up
		 * in Wordnet, and the results are matched. 
		 */
	public static int countMatchingRelatedWords(String a, String b) {
		  // Set the path to the data files
		  Dictionary.initialize("C:/Program Files/WordNet/2.1/dict");
		  
		  // Get an instance of the Dictionary object
		  Dictionary dict = Dictionary.getInstance();
		  
		  // Declare a filter for all terms starting with "car", ignoring case
		 String a_pharsedName = pharseString(a);
		 String b_pharsedName = pharseString(b);
//		 TermFilter a_filter = new StartsWithFilter(a, true);
//		 TermFilter b_filter = new StartsWithFilter(b, true);
//		  
		  // Get an iterator to the list of nouns
//		  Iterator<IndexTerm> a_itr_nouns = dict.getIndexTermIterator    (PartOfSpeech.NOUN, -1, a_filter);
//		  Iterator<IndexTerm> b_itr_nouns = dict.getIndexTermIterator    (PartOfSpeech.NOUN, -1, b_filter);
//		  
		 int mathcing_nouns = 0;   
		 if (shouldTest(a_pharsedName ,b_pharsedName)){ 
		 mathcing_nouns =  extractAllMatchingWords
		  (a_pharsedName, b_pharsedName, dict);
		  
		 }
//		  Iterator<IndexTerm> a_itr_verbs = dict.getIndexTermIterator    (PartOfSpeech.VERB, -1, a_filter);
//		  Iterator<IndexTerm> b_itr_verbs = dict.getIndexTermIterator    (PartOfSpeech.VERB, -1, b_filter);
//		  
		  int matching_verbs = 0;
		  if (shouldTest(a_pharsedName ,b_pharsedName)){
		  matching_verbs+= extractAllMatchingWords
		  (a_pharsedName, b_pharsedName, dict);
		  }
		  return matching_verbs + mathcing_nouns ;
		
	}


	private static boolean shouldTest(String name, String name2) {
			if (name.contains(name2) || name2.contains(name) )
				return false;
			else
				return true;
		}


	private static int extractAllMatchingWords(String a_pharsedName,
			String b_pharsedName , Dictionary dict) {
		Vector<String > a_related_words = new Vector<String>();
		  Vector<String> b_related_words = new Vector<String >();
		  
		 StringTokenizer a_st = new StringTokenizer(a_pharsedName);
		 StringTokenizer b_st = new StringTokenizer(b_pharsedName);
		 
		 while (a_st.hasMoreTokens()){
			 
			 TermFilter a_filter = new StartsWithFilter(a_st.nextToken(), true);
			 Iterator<IndexTerm> a_itr = dict.getIndexTermIterator    (PartOfSpeech.NOUN, -1, a_filter);
			 a_related_words.addAll(GetAllRelatedWords( a_itr ));
		 }
		 
		 while(b_st.hasMoreTokens()){
			 
			 TermFilter b_filter = new StartsWithFilter(b_st.nextToken(), true);
			 Iterator<IndexTerm> b_itr = dict.getIndexTermIterator    (PartOfSpeech.NOUN, -1, b_filter);
			 b_related_words.addAll(GetAllRelatedWords(b_itr));
		 }
	
		 return compateRelatedWords(a_related_words, b_related_words);
		 
	
	}
	
	
	private static int compateRelatedWords(Vector<String> a_related_words,
			Vector<String> b_related_words) {
		int matching_counter = 0 ;
		
		for (String  a_rel_word : a_related_words  )
			for ( String b_rel_word : b_related_words) {
				if ( a_rel_word.matches(b_rel_word) 
						|| 
					b_rel_word.matches(a_rel_word)) {
					System.out.println(" match : " + a_rel_word 
					+ " :: " + b_rel_word);
					matching_counter ++ ;
					
				}
			}
		return matching_counter;
	}


	private static Vector<String>  GetAllRelatedWords
	(Iterator<IndexTerm> itr) {
			
	
		Vector<String> related_words = new Vector<String>();
 		while (itr.hasNext()) { 
 		
 			IndexTerm it = itr.next();
 			Synset[] s = it.getSynsets();
 				
 			for(int i = 0 ; i < s.length ; i++) {
 				ArrayList<WordData > al = (ArrayList<WordData>) s[i].getWord();
 				for ( WordData wd :al ) {
 					
 					if (!related_words.contains(wd.getWord())) 
 						related_words.add(wd.getWord());
 					
 				}
 			}
 				
 			
 				
  		}
 		
 		return related_words;
		
	}


	private static String pharseString(String m_class_name) {
		
		String tmp_class_name = new String(m_class_name);
		for ( int i=1 ; i < tmp_class_name.length() ; i++) {
			
			String sub_s = tmp_class_name.substring(i, i+1);
			
			if (sub_s.matches("[A-Z]")){
				tmp_class_name = tmp_class_name.replaceAll(sub_s, " " + sub_s.toLowerCase());
			}
					
		}
		
		return tmp_class_name.replaceAll("_", " ").toLowerCase();
	}
	
	
	public static void main(String [] args) {
	
		System.out.println("total words matched : " 
				+ WordNet.countMatchingRelatedWords("DogFace" , "LegHound"));	
	}

}
